/*
 * Copyright (c) 2008, 2010
 *      Toni Spets <toni.spets@iki.fi>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <string.h>
#include "sockets.h"

int net_state = 0;

void net_init()
{
#ifdef __WIN32
	if(net_state) return;
	WSADATA wsaData;
	WSAStartup(0x0101, &wsaData);
	net_state = 1;
#endif
}

void net_free()
{
#ifdef __WIN32
	if(!net_state) return;
	WSACleanup();
	net_state = 0;
#endif
}

/* still used for LanGame mode */
uint8_t net_broadcast(uint16_t sock) {
	uint8_t yes = 1;
	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &yes, sizeof(yes));
	return yes;
}

uint8_t net_reuse(uint16_t sock) {
	int8_t yes = 1;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &yes, sizeof(yes));
	return yes;
}

uint8_t net_address(struct sockaddr_in *addr, char *host, uint16_t port) {
	// resolve host to ip
	struct hostent *hent;
	hent = gethostbyname(host);
	if(!hent) {
		fprintf(stderr, "Error resolving host '%s' to ip\n", host);
		return 0;
#ifndef SERVER
	} else {
		fprintf(stderr, "Server host resolved to '%s'\n", inet_ntoa(*(struct in_addr *)hent->h_addr_list[0]));
#endif
	}
	return net_address_ex(addr, *(int *)hent->h_addr_list[0], port);
}

uint8_t net_address_ex(struct sockaddr_in *addr, uint32_t ip, uint16_t port)
{
	int size = sizeof(struct sockaddr_in);
	memset(addr, 0, size);
	addr->sin_family = AF_INET;
	addr->sin_addr.s_addr = ip;
	addr->sin_port = htons(port);
	return 1;
}

int32_t net_recv(uint16_t sock, char *buf, uint32_t len, struct sockaddr_in *who) {
#ifdef _WIN32
	int tmp = sizeof(struct sockaddr);
#else
	size_t tmp = sizeof(struct sockaddr);
#endif
	return recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)who, &tmp);
}
